package com.yjc.manager;

import com.yjc.api.annotation.Api;
import com.yjc.manager.holder.ClassHolder;
import org.apache.commons.lang3.StringUtils;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 实例类型工厂
 *
 * @author 闫佳成
 * @version: 1.0
 * @since 2024/10/9 9:58
 */
public class ObjectBeanFactory {
    private final ClassHolder classHolder;

    private Map<Class<?>, Object> objectMap = new ConcurrentHashMap<>();

    public ObjectBeanFactory(ClassHolder classHolder){
        this.classHolder = classHolder;
    }

    public <T> T getObject(Class<T> interfaceClass){
        Object obj = objectMap.get(interfaceClass);
        if (obj == null){
            Class<?> clazz = getClass(interfaceClass);
            if (clazz != null){
                try {
                    obj = clazz.newInstance();
                } catch (Exception e) {
                    throw new RuntimeException("获取对象实例失败");
                }
                objectMap.put(interfaceClass, obj);
            }
        }
        return (T)obj;
    }

    /**
     * 获取加载类
     * @param jarName jar包名称
     * @param interfaceClass 接口
     * @return
     */
    public Class<?> getClass(String jarName,Class<?> interfaceClass){
        if (StringUtils.isBlank(jarName)){
            Api api = interfaceClass.getAnnotation(Api.class);
            if (api != null){
                jarName = api.jarName();
            }
        }
        if (StringUtils.isBlank(jarName)){
            Set<String> jarNames = classHolder.getClassJarMap().get(interfaceClass);
            if (jarNames != null){
                jarName = jarNames.iterator().next();
            }
        }
        Map<Class<?>, Class<?>> interfaceClassMap = classHolder.getJarInterfaceMap().get(jarName);
        if (interfaceClassMap != null){
            return interfaceClassMap.get(interfaceClass);
        }
        return null;
    }

    public Class<?> getClass(Class<?> interfaceClass){
        return getClass(null, interfaceClass);
    }

    public void clear(){
        objectMap.clear();
    }
}
